home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
ArrangeScript
/
Sources
/
ArrangeScript.cp
< prev
next >
Wrap
Text File
|
1996-06-21
|
5KB
|
205 lines
/*
This file defines a "generic" plugin module for Arrange 2.0.
To use it, you should modify the file 'SubClass.h', which subclasses
the Plugin class definition by adding new fields and private functions,
and implementing the appropriate methods in this C++ source file.
*/
#include "ArrangeScript.h"
#ifndef __APPLEEVENTS__
#include <AppleEvents.h>
#endif
#ifndef __AEREGISTRY__
#include <AERegistry.h>
#endif
#ifndef __COMPONENTS__
#include <Components.h>
#endif
#ifndef __OSA__
#include <OSA.h>
#endif
// Function prototypes
static pascal OSErr HandlerGlue(AppleEvent* message, AppleEvent* reply, long refCon);
/*************************************************************************/
/**************************** GenericPlugin ******************************/
/*************************************************************************/
ArrangeScript::ArrangeScript (const ArrangeCallbackTbl* theCalls) :
Plugin (theCalls),
fWildCardHandler(NULL)
{
// Add an item to the About Plugins menu for this plugin.
calls->ui->AddMenuItem(mPluginAbout, aboutMenuText, 0, aboutCmdCode, 0);
calls->ui->SetMenuItem(mPluginAbout, aboutCmdCode, 0, NULL, true, 0, 0);
InstallMenuHook(0, true, aboutCmdCode);
// Add a new scripting menu
// calls->ui->AddMenu(mScriptingText, mScripting, 0);
calls->ui->AddMenuItem(mTools, mExecuteMenuText, 0, mExecuteCmdCode, 0);
InstallMenuHook(0, true, mExecuteCmdCode);
// InstallEventHandlers();
}
arHookResult ArrangeScript::MenuEvent(Integer commandCode,
Integer commandParam,
pShort modifiers)
{
arHookResult result;
switch (commandCode)
{
case aboutCmdCode:
Alert(qModuleRsrcID, NULL);
result = true;
break;
case mExecuteCmdCode:
{
Integer selStart;
Integer selEnd;
Integer selResult;
// get text size
selResult = calls->sel->GetSelText(0, NULL, &selStart, &selEnd);
if ((selResult > 0) && (selEnd > selStart))
{
long bufferSize = selEnd + 1;
Handle buffer = (Handle)AllocMem(bufferSize, amHdl);
if (buffer)
{
HLock(buffer);
selResult = calls->sel->GetSelText(bufferSize, *buffer, &selStart, &selEnd);
AEDesc scriptDesc;
scriptDesc.descriptorType = typeNull;
scriptDesc.dataHandle = NULL;
AECreateDesc(typeChar, *(buffer + selStart), selEnd - selStart, &scriptDesc);
DeallocMem(buffer, amHdl);
ExecuteText(scriptDesc);
AEDisposeDesc(&scriptDesc);
}
}
else
{
StopAlert("Cannot execute. No text is selected.");
}
result = true;
}
break;
default:
result = false;
}
return result;
}
ArrangeScript::~ArrangeScript ()
{
if (fWildCardHandler)
{
AERemoveEventHandler(typeWildCard, typeWildCard, fWildCardHandler, false);
DisposeRoutineDescriptor(fWildCardHandler);
fWildCardHandler = NULL;
}
}
void ArrangeScript::InstallEventHandlers()
{
fWildCardHandler = NewAEEventHandlerProc(HandlerGlue);
if (fWildCardHandler)
AEInstallEventHandler(typeWildCard, typeWildCard, fWildCardHandler, (long)this, false);
}
void ArrangeScript::ExecuteText(AEDesc& desc)
{
ComponentInstance defaultComponent =
OpenDefaultComponent(kOSAComponentType, kOSAGenericScriptingComponentSubtype);
OSAID newScriptID = kOSANullScript;
OSAID resultID = kOSANullScript;
OSAError osaErr;
AEDesc resultText;
resultText.descriptorType = typeNull;
resultText.dataHandle = NULL;
//osaErr = OSACompileExecute(defaultComponent, &desc, kOSANullScript, kOSAModeCanInteract, &resultID);
osaErr = OSADoScript(defaultComponent, &desc, kOSANullScript, typeChar, kOSAModeCanInteract, &resultText);
if (osaErr != noErr)
{
if (resultText.dataHandle && resultText.descriptorType == typeChar)
{
long startSize = GetHandleSize(resultText.dataHandle);
SetHandleSize(resultText.dataHandle, startSize + 1);
HLock(resultText.dataHandle);
*((*resultText.dataHandle) + startSize) = 0;
StopAlert((char*)**resultText.dataHandle);
HUnlock(resultText.dataHandle);
}
else
StopAlert("An error occurred compiling and executing the script.");
}
AEDisposeDesc(&resultText);
CloseComponent(defaultComponent);
}
arDocumentPtr ArrangeScript::MakeFrontDocCurrent()
{
// fast and loose...assumes at least one doc is open
arDocumentPtr oldDoc = calls->doc->GetCurrentDoc();
calls->doc->SetCurrentDoc(GetIndexedDoc(0));
return oldDoc;
}
void ArrangeScript::DoCreateElementEvent(AppleEvent* message, AppleEvent* reply)
{
arDocumentPtr oldDoc = MakeFrontDocCurrent();
arTypeID builtInType = calls->sysObj->GetBuiltInObject(boNoteDefType);
arNoteID newNote = CreateNote(arNoteType, true);
arTopicID curTopic = calls->sysObj->GetCurrentTopic(calls->sel->GetActiveWindow(), true);
calls->data->AddListFieldEntry(curTopic, 0, 0, newNote, nullSFF);
calls->doc->SetCurrentDoc(oldDoc);
}
static pascal OSErr HandlerGlue(AppleEvent* message,
AppleEvent* reply,
long refCon)
{
OSErr result;
AEKeyword eventID;
AEKeyword actualType;
long actualSize;
ArrangeScript* plugin = (ArrangeScript*)refCon;
AEGetAttributePtr(message, keyEventIDAttr, typeType, &actualType, &eventID, sizeof(AEKeyword), &actualSize);
switch (eventID)
{
case kAECreateElement:
plugin->DoCreateElementEvent(message, reply);
result = noErr;
break;
default:
result = errAEEventNotHandled;
}
return result;
}